<template>
  <div class="version-control-container">
    <div class="page-header">
      <h1>版本控制</h1>
      <p>应用ID: {{ appId }}</p>
    </div>

    <div class="content-wrapper">
      <!-- 左侧文件树 -->
      <div class="file-tree-container">
        <div class="file-tree-header">
          <h3>文件列表</h3>
          <a-button type="primary" size="small" @click="refreshFileTree">
            <template #icon>
              <RestOutlined />
            </template>
            刷新
          </a-button>
        </div>

        <div v-if="loading" class="loading-container">
          <a-spin tip="加载文件列表中..." />
        </div>

        <div v-else-if="error" class="error-container">
          <a-alert message="加载失败" :description="error" type="error" show-icon />
          <a-button type="primary" @click="loadFileList">重试</a-button>
        </div>

        <div v-else-if="!fileTree.length" class="empty-container">
          <a-empty description="暂无文件" />
        </div>

        <div v-else class="file-tree">
          <a-tree
            :tree-data="fileTree"
            :default-expand-all="true"
            @select="handleFileSelect"
            :selectable="true"
            :disabledKeys="disabledKeys"
          >
            <template #title="{ title, key, node }">
              <span :class="['file-tree-node', { 'file-type': node?.type === 'FILE' }]">
                {{ title }}
                <span v-if="node?.type === 'DIRECTORY'" class="node-type-tag">目录</span>
                <span v-else-if="node?.type === 'FILE'" class="node-type-tag file-tag">文件</span>
              </span>
            </template>
          </a-tree>
        </div>
      </div>

      <!-- 右侧文件内容 -->
      <div class="file-content-container">
        <div class="file-content-header">
          <h3>{{ selectedFile?.fileName || '未选择文件' }}</h3>
          <a-tag v-if="selectedFile?.fileExtension" color="blue">{{ selectedFile.fileExtension }}</a-tag>
        </div>

        <div v-if="contentLoading" class="content-loading-container">
          <a-spin tip="加载文件内容中..." />
        </div>

        <div v-else-if="contentError" class="content-error-container">
          <a-alert message="加载文件内容失败" :description="contentError" type="error" show-icon />
        </div>

        <div v-else-if="!selectedFile" class="empty-content-container">
          <a-empty description="请选择一个文件查看内容" />
        </div>

        <div v-else class="file-content-wrapper">
          <!-- 代码对比或单文件展示区域 -->
          <div v-if="showDiff && historyCode" class="code-diff-container">
            <div class="code-diff-header">
              <div class="code-diff-title">
                <span class="current-version">当前版本</span>
                <span class="vs">VS</span>
                <span class="history-version">{{ selectedHistory?.description || '历史版本' }}</span>
              </div>
              <div class="diff-stats-wrapper">
                <div class="diff-stats">
                  <span class="added-stats">+ {{ addedLinesCount }} 行</span>
                  <span class="deleted-stats">- {{ deletedLinesCount }} 行</span>
                </div>
                <a-button size="small" @click="cancelDiff">关闭对比</a-button>
              </div>
            </div>

            <div v-if="historyCodeLoading" class="history-code-loading">
              <a-spin tip="加载历史版本代码中..." />
            </div>

            <div v-else-if="historyCodeError" class="history-code-error">
              <a-alert message="加载失败" :description="historyCodeError" type="error" show-icon />
            </div>

            <div v-else class="code-diff-content">
              <!-- 自定义差异比较显示 -->
              <div class="custom-diff-container">
                <div v-if="diffLines.length > 0" class="diff-table">
                  <div class="diff-header">
                    <div class="diff-column">行号</div>
                    <div class="diff-column old-content">旧版本</div>
                    <div class="diff-column">行号</div>
                    <div class="diff-column new-content">新版本</div>
                  </div>
                  <div 
                    v-for="(diffLine, index) in diffLines" 
                    :key="index" 
                    class="diff-row"
                    :class="{ 'added': diffLine.type === 'added', 'deleted': diffLine.type === 'deleted', 'modified': diffLine.type === 'modified' }"
                  >
                    <div class="diff-column">{{ diffLine.oldLineNum || '-' }}</div>
                    <div class="diff-column old-content">{{ diffLine.oldLine || '' }}</div>
                    <div class="diff-column">{{ diffLine.newLineNum || '-' }}</div>
                    <div class="diff-column new-content">{{ diffLine.newLine || '' }}</div>
                  </div>
                </div>
                <div v-else class="no-diff-message">
                  <p style="color: #52c41a;">代码内容相同（忽略格式差异）</p>
                </div>
              </div>
            </div>
          </div>

          <!-- 单文件展示区域 -->
          <div v-else class="single-file-content">
            <pre><code :class="`language-${getFileLanguage(selectedFile.fileExtension)}`">{{ selectedFile.content }}</code></pre>
          </div>
        </div>

        <!-- 文件历史版本列表 -->
          <div v-if="selectedFile" class="file-history-container">
          <div class="file-history-header">
            <h4>历史版本</h4>
          </div>

          <div v-if="historyLoading" class="history-loading-container">
            <a-spin size="small" />
          </div>

          <div v-else-if="historyError" class="history-error-container">
            <a-alert message="加载失败" :description="historyError" type="error" show-icon banner size="small" />
          </div>

          <div v-else-if="fileHistory.length === 0" class="history-empty-container">
            <a-empty description="暂无历史版本" size="small" />
          </div>

          <div v-else class="file-history-list">
            <div
              v-for="(history, index) in fileHistory"
              :key="index"
              class="file-history-item"
              :class="{ 'selected': selectedHistory === history }"
              @click="handleHistorySelect(history)"
            >
              <div class="history-item-header">
                <div class="history-description-wrapper">
                  <span class="history-description">{{ history.description || '无描述' }}</span>
                  <span v-if="history.version === currentVersionId || index === fileHistory.length - 1" class="current-version-tag">当前版本</span>
                </div>
                <div class="history-meta">
                  <span class="history-time">{{ formatTime(history.createTime) }}</span>
                </div>
              </div>
              <div class="history-item-footer">
                <span class="history-author">修改人: {{ history.createdBy || '未知' }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import { useRoute } from 'vue-router'
import { RestOutlined } from '@ant-design/icons-vue'
import { getLatestFileList, getFileContentByNameAndId, getFileHistoryByNameAndId, getFileContentByVersion } from '@/api/appVersionCtlController'
import { CodeDiff } from 'v-code-diff'
// 类型从 typings.d.ts 文件中获取，不需要作为模块导入

const route = useRoute()
// 直接使用字符串形式的ID，避免大整数精度丢失
const appId = computed(() => route.params.id.toString())

// 文件树相关状态
const fileTree = ref<any[]>([])
const loading = ref(false)
const error = ref('')
const disabledKeys = ref<string[]>([])
const currentVersionId = ref<number | null>(null)

// 文件内容相关状态
const selectedFile = ref<any>(null)
const contentLoading = ref(false)
const contentError = ref('')

// 文件历史版本相关状态
const fileHistory = ref<any[]>([])
const historyLoading = ref(false)
const historyError = ref('')
const selectedHistory = ref<any>(null)
const historyCode = ref<any>(null)
const historyCodeLoading = ref(false)
const historyCodeError = ref('')
const showDiff = ref(false)
const diffLines = ref<any[]>([])
const addedLinesCount = ref(0)
const deletedLinesCount = ref(0)

// 精确比较代码行并返回详细的差异信息（全量显示，高亮差异）
const compareCodeLines = (oldCode: string | undefined | null, newCode: string | undefined | null) => {
  const oldLines = (oldCode || '').split('\n')
  const newLines = (newCode || '').split('\n')
  const result: any[] = []
  
  // 规范化每行代码，去除空白和格式差异
  const normalizeLine = (line: string) => {
    // 去除行尾空格和制表符，然后去除开头和结尾的空白
    return line.replace(/[ \t]+$/, '').trim()
  }
  
  // 计算每行的差异类型
  const maxLines = Math.max(oldLines.length, newLines.length)
  
  // 为全量显示构建结果，包括所有行
  for (let i = 0; i < maxLines; i++) {
    const oldLine = i < oldLines.length ? oldLines[i] : ''
    const newLine = i < newLines.length ? newLines[i] : ''
    const oldNormalized = normalizeLine(oldLine)
    const newNormalized = normalizeLine(newLine)
    
    // 确定行的差异类型
    let type: string = 'unchanged'
    
    if (i >= oldLines.length) {
      // 新增的行
      type = 'added'
    } else if (i >= newLines.length) {
      // 删除的行
      type = 'deleted'
    } else if (oldLine !== newLine) {
      // 有变化的行
      if (oldNormalized === newNormalized) {
        // 只有格式变化，不标记为修改
        type = 'unchanged'
      } else {
        // 内容有实质性变化
        type = 'modified'
      }
    }
    
    // 添加到结果中
    result.push({
      type,
      oldLineNum: i < oldLines.length ? i + 1 : null,
      oldLine,
      newLineNum: i < newLines.length ? i + 1 : null,
      newLine
    })
  }
  
  return result
}

// 简化的格式化函数
const formatCodeForDiff = (code: string | undefined | null): string => {
  if (!code) return ''
  // 只统一换行符
  return code.replace(/\r\n/g, '\n')
}

// 获取文件树数据
const loadFileList = async () => {
  if (!appId.value || appId.value === 'undefined' || appId.value === 'null') {
    error.value = '应用ID无效'
    return
  }

  loading.value = true
  error.value = ''
  disabledKeys.value = []

  try {
      // appId保持为字符串，避免大整数精度丢失
      const response = await getLatestFileList({ appId: appId.value })
      console.log('文件列表响应:', response)

      // 访问 response.data 来获取 API 返回数据
      if (response.data && response.data.code === 0 && response.data.data) {
        // 从FileNodeVO中获取fileNodeList作为文件树数据
        const fileNodeVO = response.data.data
        console.log('FileNodeVO数据:', fileNodeVO)

        // 保存当前版本号用于历史版本高亮
        currentVersionId.value = fileNodeVO.version || null

        // 获取fileNodeList并转换为树节点格式
        const rawData = fileNodeVO.fileNodeList || []
        console.log('文件节点列表:', rawData)

        fileTree.value = convertToTreeData(rawData)

      // 收集所有目录节点的key，设置为不可选择
      collectDisabledKeys(fileTree.value)
    } else {
      error.value = response.data?.message || '获取文件列表失败'
      console.error('API返回错误:', response.data)
    }
  } catch (err: any) {
    error.value = '网络请求失败，请稍后重试'
    console.error('获取文件列表失败:', err?.message || err)
  } finally {
    loading.value = false
  }
}

// 刷新文件树
const refreshFileTree = () => {
  selectedFile.value = null
  contentError.value = ''
  loadFileList()
}

// 转换为树组件需要的数据格式
const convertToTreeData = (nodes: any[]): any[] => {
  return nodes.map((node) => {
    const treeNode: any = {
      key: node.name,
      title: node.name,
      type: node.type,
    }

    if (node.children && node.children.length > 0) {
      treeNode.children = convertToTreeData(node.children)
    }

    return treeNode
  })
}

// 收集不可选择的节点（目录节点）
const collectDisabledKeys = (nodes: any[]) => {
  if (!Array.isArray(nodes)) return

  nodes.forEach((node) => {
    if (node && node.type === 'DIRECTORY') {
      disabledKeys.value.push(node.name)
      if (node.children && Array.isArray(node.children) && node.children.length > 0) {
        collectDisabledKeys(node.children)
      }
    }
  })
}

// 处理文件选择
const handleFileSelect = async (selectedKeys: string[], info: any) => {
  if (selectedKeys.length > 0 && info.selectedNodes && info.selectedNodes.length > 0) {
    const node = info.selectedNodes[0]
    if (node && node.type === 'FILE') {
      // 重置历史版本选中状态
      selectedHistory.value = null
      historyCode.value = null
      showDiff.value = false
      await loadFileContent(node.key || node.name)
    }
  }
}

// 加载文件内容
const loadFileContent = async (fileName: string) => {
  if (!appId.value || !fileName) return

  contentLoading.value = true
  contentError.value = ''

  try {
      // 保持appId为字符串，避免大整数精度丢失
      const response = await getFileContentByNameAndId({ 
        appId: appId.value, 
        fileName 
      })

    // 访问 response.data 来获取 API 返回数据
    if (response.data && response.data.code === 0 && response.data.data) {
      selectedFile.value = response.data.data
      // 同时加载文件历史版本
      await loadFileHistory(fileName)
    } else {
      contentError.value = response.data?.message || '获取文件内容失败'
    }
  } catch (err: any) {
    contentError.value = '网络请求失败，请稍后重试'
    console.error('获取文件内容失败:', err?.message || err)
  } finally {
    contentLoading.value = false
  }
}

// 加载文件历史版本
const loadFileHistory = async (fileName: string) => {
  if (!appId.value || !fileName) return

  historyLoading.value = true
  historyError.value = ''
  fileHistory.value = []

  try {
      // 保持appId为字符串，避免大整数精度丢失
      const response = await getFileHistoryByNameAndId({ 
        appId: appId.value, 
        fileName 
      })

    // 访问 response.data 来获取 API 返回数据
    if (response.data && response.data.code === 0 && response.data.data) {
      fileHistory.value = response.data.data
    } else {
      historyError.value = response.data?.message || '获取文件历史版本失败'
      console.error('获取文件历史版本失败:', response.data)
    }
  } catch (err: any) {
    historyError.value = '网络请求失败，请稍后重试'
    console.error('获取文件历史版本失败:', err?.message || err)
  } finally {
    historyLoading.value = false
  }
}

// 处理历史版本选择
const handleHistorySelect = async (history: any) => {
  if (!history || !history.appId || !history.fileName || !history.version) return

  // 如果点击的是当前选中的历史版本，则取消选中
  if (selectedHistory.value === history) {
    selectedHistory.value = null
    historyCode.value = null
    showDiff.value = false
    return
  }

  selectedHistory.value = history
  historyCodeLoading.value = true
  historyCodeError.value = ''

  try {
    // 使用组件中的appId.value而不是history.appId，避免大整数精度丢失
    const response = await getFileContentByVersion({ 
      appId: appId.value, 
      fileName: history.fileName,
      version: history.version
    })

    if (response.data && response.data.code === 0 && response.data.data) {
      historyCode.value = response.data.data
      showDiff.value = true
      // 比较代码并提取差异行
      diffLines.value = compareCodeLines(historyCode.value.content, selectedFile.value.content)
      
      // 统计增加和删除的行数
      addedLinesCount.value = diffLines.value.filter(line => line.type === 'added').length
      deletedLinesCount.value = diffLines.value.filter(line => line.type === 'deleted').length
    } else {
      historyCodeError.value = response.data?.message || '获取历史版本代码失败'
    }
  } catch (err: any) {
    historyCodeError.value = '网络请求失败，请稍后重试'
    console.error('获取历史版本代码失败:', err?.message || err)
  } finally {
    historyCodeLoading.value = false
  }
}

// 根据文件扩展名获取语言类型
const getFileLanguage = (extension?: string): string => {
  if (!extension) return 'plaintext'

  const extensionMap: Record<string, string> = {
    html: 'html',
    css: 'css',
    js: 'javascript',
    ts: 'typescript',
    jsx: 'jsx',
    tsx: 'tsx',
    vue: 'vue',
    json: 'json',
    md: 'markdown',
    yml: 'yaml',
    yaml: 'yaml',
    xml: 'xml',
    py: 'python',
    java: 'java',
    c: 'c',
    cpp: 'cpp',
    'c++': 'cpp',
    go: 'go',
    rust: 'rust',
    php: 'php',
    sql: 'sql',
    sh: 'bash',
    bash: 'bash',
    cmd: 'batch',
    bat: 'batch',
    txt: 'plaintext'
  }

  return extensionMap[extension.toLowerCase()] || 'plaintext'
}

// 格式化时间
const formatTime = (timeStr?: string): string => {
  if (!timeStr) return ''

  try {
    const date = new Date(timeStr)
    const year = date.getFullYear()
    const month = String(date.getMonth() + 1).padStart(2, '0')
    const day = String(date.getDate()).padStart(2, '0')
    const hours = String(date.getHours()).padStart(2, '0')
    const minutes = String(date.getMinutes()).padStart(2, '0')

    return `${year}-${month}-${day} ${hours}:${minutes}`
  } catch (err) {
    console.error('时间格式化失败:', err)
    return timeStr
  }
}

// 取消代码对比
const cancelDiff = () => {
  selectedHistory.value = null
  historyCode.value = null
  showDiff.value = false
  addedLinesCount.value = 0
  deletedLinesCount.value = 0
}

// 页面加载时获取文件列表
onMounted(() => {
  loadFileList()
})
</script>

<style scoped>
.version-control-container {
  min-height: 100vh;
  background: #f5f5f5;
  padding: 24px;
}

.page-header {
  margin-bottom: 24px;
}

.page-header h1 {
  margin: 0 0 8px 0;
  font-size: 24px;
  font-weight: 600;
}

.page-header p {
  margin: 0;
  color: #666;
  font-size: 14px;
}

.content-wrapper {
  display: flex;
  gap: 24px;
  height: calc(100vh - 120px);
}

/* 左侧文件树容器 */
.file-tree-container {
  flex: 0 0 320px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.file-tree-header {
  padding: 16px;
  border-bottom: 1px solid #f0f0f0;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.file-tree-header h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
}

.file-tree {
  flex: 1;
  overflow: auto;
  padding: 8px 0;
}

.file-tree-node {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
}

.file-tree-node.file-type {
  cursor: pointer;
}

.node-type-tag {
  font-size: 10px;
  padding: 2px 6px;
  border-radius: 4px;
  background: #e6f7ff;
  color: #1890ff;
}

.node-type-tag.file-tag {
  background: #f6ffed;
  color: #52c41a;
}

/* 右侧文件内容容器 */
.file-content-container {
  flex: 1;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* 自定义差异比较样式 */
.custom-diff-container {
  padding: 16px;
  background: #fafafa;
  border-radius: 4px;
  overflow: auto;
}

.diff-table {
  border-collapse: collapse;
  width: 100%;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 14px;
}

.diff-header {
  display: flex;
  background: #f0f0f0;
  padding: 8px;
  font-weight: bold;
  border-bottom: 2px solid #e0e0e0;
  position: sticky;
  top: 0;
  z-index: 10;
}

.diff-row {
  display: flex;
  border-bottom: 1px solid #e0e0e0;
  transition: background-color 0.2s;
  background: #ffffff;
}

.diff-row:hover {
  background-color: #fafafa;
}

/* 差异行的高亮样式 */
.diff-row.added {
  background-color: #f6ffed;
}

.diff-row.deleted {
  background-color: #fff2e8;
}

.diff-row.modified {
  background-color: #e6f7ff;
}

.diff-column {
  padding: 6px 8px;
  min-width: 50px;
  text-align: right;
  color: #888;
  border-right: 1px solid #e0e0e0;
}

.diff-column.old-content,
.diff-column.new-content {
  text-align: left;
  flex: 1;
  white-space: pre-wrap;
  word-wrap: break-word;
  border-right: none;
  min-width: 300px;
}

/* 差异内容的高亮样式 */
.diff-row.added .new-content {
  color: #52c41a;
  font-weight: 500;
}

.diff-row.deleted .old-content {
  color: #ff4d4f;
  text-decoration: line-through;
}

.diff-row.modified .old-content {
  color: #1890ff;
}

.diff-row.modified .new-content {
  color: #52c41a;
  font-weight: 500;
}

.no-diff-message {
  text-align: center;
  padding: 24px;
  background: #f6ffed;
  border-radius: 4px;
  border: 1px solid #b7eb8f;
}

.file-content-header {
  padding: 16px;
  border-bottom: 1px solid #f0f0f0;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.file-content-header h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  word-break: break-all;
}

.file-content {
  flex: 1;
  overflow: auto;
  padding: 16px;
  background: #fafafa;
}

.file-content pre {
  margin: 0;
  background: #fff;
  border: 1px solid #f0f0f0;
  border-radius: 4px;
  padding: 16px;
  font-size: 14px;
  line-height: 1.6;
  white-space: pre-wrap;
  word-wrap: break-word;
  max-height: 100%;
  overflow: auto;
}

/* 加载和错误状态 */
.loading-container,
.error-container,
.empty-container,
.content-loading-container,
.content-error-container,
.empty-content-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

.error-container,
.content-error-container {
  gap: 16px;
}

/* 文件历史版本样式 */
.file-history-container {
  position: absolute;
  bottom: 24px;
  right: 24px;
  width: 360px;
  max-height: 400px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  border: 1px solid #f0f0f0;
}

.file-history-header {
  padding: 12px 16px;
  border-bottom: 1px solid #f0f0f0;
  background: #fafafa;
}

/* 代码差异统计样式 */
.diff-stats-wrapper {
  display: flex;
  align-items: center;
  gap: 16px;
}

.diff-stats {
  padding: 4px 12px;
  background-color: #f5f5f5;
  border-radius: 4px;
  display: flex;
  gap: 16px;
  font-size: 14px;
  font-weight: 500;
}

.added-stats {
  color: #52c41a;
}

.deleted-stats {
  color: #ff4d4f;
}

.file-history-header h4 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
}

.history-loading-container {
  padding: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.history-error-container {
  padding: 12px;
}

.history-empty-container {
  padding: 40px 20px;
}

.file-history-list {
  flex: 1;
  overflow-y: auto;
  max-height: 340px;
}

.file-history-item {
  padding: 12px 16px;
  border-bottom: 1px solid #f5f5f5;
  transition: background-color 0.2s;
}

.file-history-item:hover {
  background-color: #fafafa;
}

.file-history-item:last-child {
  border-bottom: none;
}

.history-item-header {
  margin-bottom: 8px;
}

.history-description-wrapper {
  display: flex;
  align-items: center;
  margin-bottom: 4px;
}

.history-description {
  flex: 1;
  font-size: 14px;
  font-weight: 500;
  color: #333;
  line-height: 1.4;
  word-break: break-word;
  margin-right: 8px;
}

.current-version-tag {
  background-color: #52c41a;
  color: white;
  font-size: 12px;
  padding: 2px 8px;
  border-radius: 10px;
  font-weight: 500;
}

.history-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.history-version-text {
  color: #1890ff;
  font-size: 12px;
  font-weight: 500;
}

.history-time {
  font-size: 12px;
  color: #8c8c8c;
  white-space: nowrap;
}

.history-item-footer {
  display: flex;
  justify-content: flex-end;
}

.history-author {
  font-size: 12px;
  color: #595959;
}

/* 文件内容展示区域 */
.file-content-wrapper {
  flex: 1;
  overflow: auto;
  display: flex;
  flex-direction: column;
  height: 100%;
}

.single-file-content {
  flex: 1;
  padding: 16px;
  background: #fafafa;
  overflow: auto;
}

.single-file-content pre {
  margin: 0;
  background: #fff;
  border: 1px solid #f0f0f0;
  border-radius: 4px;
  padding: 16px;
  font-size: 14px;
  line-height: 1.6;
  white-space: pre-wrap;
  word-wrap: break-word;
  max-height: 100%;
  overflow: auto;
}

/* 代码对比区域样式 */
.code-diff-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: #fff;
  border-radius: 4px;
  overflow: hidden;
}

.code-diff-header {
  padding: 12px 16px;
  background: #fafafa;
  border-bottom: 1px solid #f0f0f0;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.code-diff-title {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 14px;
  font-weight: 500;
}

.current-version {
  color: #52c41a;
}

.vs {
  color: #8c8c8c;
  font-size: 12px;
}

.history-version {
  color: #1890ff;
}

.code-diff-content {
  flex: 1;
  overflow: auto;
}

.history-code-loading,
.history-code-error {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 40px;
}

.history-code-error {
  flex-direction: column;
  gap: 16px;
}

/* 历史版本选择样式 */
.file-history-item {
  cursor: pointer;
  transition: all 0.2s;
}

.file-history-item:hover {
  background-color: #fafafa;
}

.file-history-item.selected {
  background-color: #e6f7ff;
  border-left: 3px solid #1890ff;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .content-wrapper {
    flex-direction: column;
    height: auto;
  }

  .file-tree-container {
    flex: none;
    max-height: 300px;
  }

  .file-content-container {
    min-height: 400px;
    position: relative;
  }

  .file-history-container {
    position: relative;
    bottom: auto;
    right: auto;
    width: 100%;
    max-height: 200px;
    margin-top: 16px;
    box-shadow: none;
  }

  .code-diff-title {
    flex-direction: column;
    gap: 4px;
    align-items: flex-start;
  }

  .code-diff-header {
    flex-direction: column;
    gap: 12px;
    align-items: flex-start;
  }
}
</style>
